import math

import pygame
import random
import sys
from config import Config
from Item import Agent, Food
from utils import *

# 初始化pygame
pygame.init()

config = Config()

# 设置网格大小和智能体数量
GRID_SIZE = config.GRID_SIZE
AGENT_COUNT = config.AGENT_COUNT
FOOD_COUNT = config.FOOD_COUNT
CELL_SIZE = config.CELL_SIZE  # 根据屏幕大小调整单元格大小
AGENT_MIN_MAX_HEALTH = config.AGENT_MIN_MAX_HEALTH
# 创建屏幕
screen = pygame.display.set_mode(config.SCREEN)
pygame.display.set_caption('智能体游戏')

# 设置字体
font = pygame.font.Font(None, config.FONT_SIZE)

# 创建智能体列表
agents = [Agent(random.randint(0, GRID_SIZE - 1), random.randint(0, GRID_SIZE - 1),
                random.randint(AGENT_MIN_MAX_HEALTH[0], AGENT_MIN_MAX_HEALTH[1])) for _ in
          range(AGENT_COUNT)]

# 创建食物列表
foods = [Food(random.randint(0, GRID_SIZE - 1), random.randint(0, GRID_SIZE - 1), random.randint(1, 10)) for _ in
         range(FOOD_COUNT)]


# 检查两个智能体是否相邻
def are_adjacent(agent_i, agent_j):
    # 判断智能体i和j是否相遇，即当两个智能体相交
    agent_i_agent_j_center_distance = CELL_SIZE * math.sqrt(
        (abs(agent_i.x - agent_j.x)) ** 2 + (abs(agent_i.y - agent_j.y)) ** 2)
    if agent_i_agent_j_center_distance < (agent_i.size + agent_j.size) // 2:
        return True
    else:
        return False


def agent_i_kill_agent_j(agent_i, agent_j):
    # 智能体i击杀j
    agent_i.health = agent_i.health - agent_j.health
    agent_i.level_up_kill_number += agent_j.level


def agent_i_eat_food_i(agent_i, food_i):
    # 智能体i吃掉食物i
    agent_i.health = agent_i.health + food_i.satiety
    agent_i.level_up_kill_number += food_i.satiety / 10


def check_state():
    best_agent = 0
    best_agent_score = -999
    for i in range(AGENT_COUNT):
        if agents[i].get_agent_score() > best_agent_score:
            best_agent = agents[i]
            best_agent_score = agents[i].get_agent_score()
    # 输出智能体最高的血量，使用\r避免重复输出
    print(
        f"\r最佳智能体: {best_agent.level} 血量: {round(best_agent.health, 2)} / {best_agent.max_health} 升级: {best_agent.level_up_kill_number} / {best_agent.level}",
        end="")
    # print(f"\r血量: {best_agent.health}", end="")

    return best_agent


# 游戏主循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((255, 255, 255))

    # 绘制食物
    for food in foods:
        food.draw()

    # 移动智能体并检测碰撞
    for i in range(AGENT_COUNT):
        # 计算智能体的5x5邻居，用于评估智能体下一步走向
        neighbors = []
        DETECT_RANGE = agents[i].detect_range
        for j in range(AGENT_COUNT):
            if agents[i].x - DETECT_RANGE < agents[j].x < agents[i].x + DETECT_RANGE and agents[i].y - DETECT_RANGE < \
                    agents[j].y < agents[i].y + DETECT_RANGE and i != j:
                neighbors.append(agents[j])

        agents[i].move(neighbors)
        agents[i].draw()
        agents[i].step()

    # 检测相邻智能体并处理相遇
    for i in range(AGENT_COUNT):
        for j in range(i + 1, AGENT_COUNT):
            if are_adjacent(agents[i], agents[j]):
                if agent_i_can_kill_agent_j(agents[i], agents[j]):
                    agent_i_kill_agent_j(agents[i], agents[j])
                    agents[j] = Agent(random.randint(0, GRID_SIZE - 1), random.randint(0, GRID_SIZE - 1),
                                      random.randint(AGENT_MIN_MAX_HEALTH[0], AGENT_MIN_MAX_HEALTH[1]))
                else:
                    agent_i_kill_agent_j(agents[j], agents[i])
                    agents[i] = Agent(random.randint(0, GRID_SIZE - 1), random.randint(0, GRID_SIZE - 1),
                                      random.randint(AGENT_MIN_MAX_HEALTH[0], AGENT_MIN_MAX_HEALTH[1]))

    # 移动智能体并检测碰撞
    for i in range(AGENT_COUNT):
        # 检查智能体是否与食物重合
        for j in range(FOOD_COUNT):
            if are_adjacent(agents[i], foods[j]):
                agent_i_eat_food_i(agents[i], foods[j])
                foods[j] = Food(random.randint(0, GRID_SIZE - 1), random.randint(0, GRID_SIZE - 1),
                                random.randint(1, 10))

    check_state()

    pygame.display.flip()
    pygame.time.delay(100)  # 每秒更新一次

# 退出游戏
pygame.quit()
sys.exit()
